package com.pai4j.aigc.llm.service;

import com.pai4j.aigc.llm.entity.LLMModelEntity;
import com.pai4j.aigc.llm.entity.LLMUserBindingEntity;
import com.pai4j.aigc.llm.repository.dao.ILLMModelDAO;
import com.pai4j.aigc.llm.repository.dao.ILLMUserBindingDAO;
import jakarta.transaction.Transactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
public class LLMModelService {

    @Autowired
    private ILLMModelDAO modelDAO;

    @Autowired
    private ILLMUserBindingDAO bindingDAO;

    public List<LLMModelEntity> listEnabledModels(String tenantId) {
        return modelDAO.findByTenantIdAndStatus(tenantId, 1);
    }

    public Optional<LLMModelEntity> findByCode(String tenantId, String code) {
        return modelDAO.findByTenantIdAndCode(tenantId, code);
    }

    public Optional<LLMModelEntity> getDefaultModel(String tenantId) {
        return modelDAO.findFirstByTenantIdAndIsDefaultAndStatus(tenantId, 1, 1);
    }

    /**
     * Find by globally unique code (no tenant restriction), used as fallback when no tenant/user model.
     */
    public Optional<LLMModelEntity> findByGlobalCode(String code) {
        return modelDAO.findByCode(code);
    }

    @Transactional
    public LLMModelEntity createOrUpdate(LLMModelEntity entity) {
        LocalDateTime now = LocalDateTime.now();
        if (entity.getId() == null) {
            entity.setCreateDate(now);
        }
        entity.setUpdateDate(now);
        // 如果设置为默认，则取消其他默认
        if (entity.getIsDefault() != null && entity.getIsDefault() == 1) {
            List<LLMModelEntity> list = modelDAO.findByTenantIdAndStatus(entity.getTenantId(), 1);
            for (LLMModelEntity m : list) {
                if (!m.getId().equals(entity.getId()) && m.getIsDefault() != null && m.getIsDefault() == 1) {
                    m.setIsDefault(0);
                    m.setUpdateDate(now);
                    modelDAO.save(m);
                }
            }
        }
        return modelDAO.save(entity);
    }

    @Transactional
    public void delete(Long id) {
        modelDAO.deleteById(id);
    }

    @Transactional
    public LLMUserBindingEntity bindUserModel(String tenantId, String userId, Long modelId, String operator) {
        LLMUserBindingEntity binding = bindingDAO.findFirstByTenantIdAndUserIdAndActiveOrderByUpdateDateDesc(tenantId, userId, 1)
                .orElseGet(LLMUserBindingEntity::new);
        binding.setTenantId(tenantId);
        binding.setUserId(userId);
        binding.setModelId(modelId);
        binding.setActive(1);
        LocalDateTime now = LocalDateTime.now();
        if (binding.getId() == null) {
            binding.setCreateDate(now);
            binding.setCreateBy(operator);
        }
        binding.setUpdateDate(now);
        binding.setUpdateBy(operator);
        return bindingDAO.save(binding);
    }

    public Optional<LLMModelEntity> findActiveModelForUser(String tenantId, String userId) {
        return bindingDAO.findFirstByTenantIdAndUserIdAndActiveOrderByUpdateDateDesc(tenantId, userId, 1)
                .flatMap(b -> modelDAO.findById(b.getModelId()));
    }
}
